package com.cainli.image.gif;

import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Handler;

import com.cainli.image.gif.GifDecoder.GifFrame;

/**
 * 
 * @author cainli 2013-1-31 下午4:42:55
 * 
 */
public class GifDrawable extends AnimationDrawable implements
		GifDecoder.DecoderCallBack {
	private static final String TAG = GifDrawable.class.getSimpleName();
	public static final int DENSITY_NONE = 0;
	public static final int ASYNC_DECODE = 0x01;
	public static final int SYNC_DECODE = 0x02;
	private int decodeType = SYNC_DECODE;
	private Context context;
	private boolean hadDecoded = false;
	private boolean hadStarted = false;
	private int delay = -1;
	private Handler mHandler = new Handler();
	private String path;
	private int mWidth = -1;
	private int mHeight = -1;
	private GifDecoder decoder = new GifDecoder();

	public GifDrawable(Context context, String path) {
		super();
		if (context == null) {
			throw new IllegalArgumentException("context can't null");
		}
		this.context = context;
		setOneShot(false);
		this.path = path;
		/*
		 * 读取头为了读取图片大小，得到图片size 
		 * 所以必须添加回调，设置drawable 大小
		 */
		decoder.setCallBack(this);
		decoder.read(path, true);
	}

	/**
	 * 设置解码方式 {@link ASYNC_DECODE},or {@link SYNC_DECODE}, default is
	 * {@link SYNC_DECODE},
	 * 
	 * @param decodeType
	 */
	public void setDecodeType(int decodeType) {
		this.decodeType = decodeType;
	}

	/**
	 * 解码
	 */
	private void decode() {
		hadDecoded = true;
		if (path == null || "".equals(path)) {
			return;
		}
		new AsyncTask<Void, Void, List<GifFrame>>() {
			@Override
			protected List<GifFrame> doInBackground(Void... params) {
				switch (decodeType) {
				case ASYNC_DECODE:
					decoder.setCallBack(GifDrawable.this);
				case SYNC_DECODE:
					break;
				default:
					break;
				}
				decoder.read(path, false);
				return decoder.getFrames();
			}

			@Override
			protected void onPostExecute(List<GifFrame> result) {
				if (result != null && getNumberOfFrames() < result.size()) {
					for (GifFrame frame : result) {
						addFrame(new BitmapDrawable(context.getResources(),
								frame.image.get()), frame.delay);
					}
				}
				start();
			};

		}.execute();
	}

	@Override
	public void draw(Canvas canvas) {
		super.draw(canvas);
		if (!hadDecoded) {
			decode();
		}
	}

	@Override
	public void onGetOneFrame(final GifFrame frame, int index,
			long nextFrameTime) {
		// 此方法在非UI线程
		Runnable runnable = new Runnable() {
			@Override
			public void run() {
				addFrame(
						new BitmapDrawable(context.getResources(), frame.image.get()),
						frame.delay);
				start();
			}
		};
		if (delay == -1) { // 第一帧
			mHandler.post(runnable);
		} else {
			long now = android.os.SystemClock.uptimeMillis();
			if (now < nextFrameTime) {
				mHandler.postDelayed(this, nextFrameTime - now);
			} else {
				mHandler.post(runnable);
			}
		}
	}

	@Override
	public void onGetGifSize(final int width, final int height) {
		mWidth = width;
		mHeight = height;
	}

	@Override
	public int getIntrinsicHeight() {
		if (mHeight != -1) {
			return mHeight;
		}
		return super.getIntrinsicHeight();
	}

	@Override
	public int getIntrinsicWidth() {
		if (mWidth != -1) {
			return mWidth;
		}
		return super.getIntrinsicWidth();
	}

	@Override
	public void start() {
		if (!hadStarted) {
			super.start();
			hadStarted = true;
		}
	}
}
